use FindBin qw[ $Bin ];
use Data::Dump qw[ dump ];
use Path::Class;
use lib dir($Bin, '..', '..', 'lib')->stringify;
use HTTP::Date qw[ time2iso ];
use QAInfo::DataSource::EmailReports;
use QAInfo::Schema::InfoDB;
use QAInfo::Info2Schema::Info2DB;
use YAML 'LoadFile';
use strict;

# =============================================================
# Constants
my $WDS = '\\'; # microsoft Windows Directory Separator
my $VIN_BUILD_SERV = 'vinnt066';

my $VERSION_RE = '\d?\d\.\d\d\.\d\d\d\.\d\d\d'; # 9.51.200.008
# =============================================================

my $config = LoadFile( file($Bin, '..', '..', 'qainfo.yml') );

# =============================================================
# Data source configuration

my $old_dns    = $config->{'Model::InfoV2'}->{'dns'};
my $old_schema = QAInfo::Info2Schema::Info2DB->connect($old_dns)
                 or die "Failed to connect to $old_dns";
# =============================================================

my $dns    = $config->{'Model::InfoDB'}->{'dns'};
my $schema = QAInfo::Schema::InfoDB->connect($dns)
             or die "Failed to connect to $dns";

# Languages
my $lng_rs = $schema->resultset('Languages');
my @langs  = $schema->get_languages_list;
my $all_langs_re = join '|', @langs;
print $all_langs_re;

# Editins
my $edt_rs   = $schema->resultset('Editions');

# Network builds
my $net_bld  = $schema->resultset('NetworkBuilds');

# Computers
my $comp_rs  = $schema->resultset('Computers');

# OS
my $os_rs    = $schema->resultset('Os');

# Users
my $users_rs = $schema->resultset('Users');

# Testplans
my $tp_rs    = $schema->resultset('Testplans');

# Reports
my $rep_rs   = $schema->resultset('Reports');

# Upgrade info
my $upg_rs   = $schema->resultset('Upgradeinfo');



my @tables = qw [ AllBuilds BuildsFolder CompStatus Images Scheduler SilkInfo Tasks Upgradematrix Whiteboard];
print "Upgrade Info 2 -> 3 Started...";


my $old_builds = $old_schema->resultset('AllBuilds');
my $old_whitebord = $old_schema->resultset('Whiteboard');

# Following RE tries to get language, version and edition from the path
# String (?:.*?$WDS) skips some special data like 'nightly', '4voice' etc
warn "Starting....\n";

print "1. Upgrade table AllBuilds\n;";
=pod
# +==== Upgrade builds
foreach my $old_build ($old_builds->all) {
    my $path = $old_build->build_path;
    if ( $path =~ m[($all_langs_re) # Lang list
                    /(?:\S+/)?      # Special. Like nightly, 4voice etc (EOM)
                    ($VERSION_RE)   # Version 
                    /(\S+)$]ix )    # Edition, Copyprotected, Media and type
    {
        my ($language, $version, $edition_info) = ($1, $2, $3);
        my $special;
        # fix special 
        $special = $1 if $path =~ m[$language/(.+?)/$version];

        my ($edition, $protection, $build_type, $media);
        if ( $edition_info =~ /^(\S+?)(?:_(CopyProtection))?\.([^_]+)(?:_(\S+))?/i ) {
            ($edition, $protection, $build_type, $media) = ($1, $2, $3, $4);
        }
        else {
            print "bad edition $edition_info\n";
            next;
        }

        my $existing_lang = $lng_rs->search({'name' => $language})->first;
        unless ( defined $existing_lang ) {
            print "$existing_lang not defined\n";
            next;
        }
        my $edition_record = {
                               'name'       => $edition,
                               'protection' => $protection,
                               'oem'        => $special,
                               'media'      => $media,
                               'build_type' => $build_type
                             };

        my $existing_edt  = $edt_rs->search($edition_record)->first;
        if (!defined $existing_edt) {
            $edt_rs->create($edition_record);
            $existing_edt = $edt_rs->search($edition_record)->first;
        }

        my $location = ( $path =~ /$VIN_BUILD_SERV/ ) ? 'vin' : 'bur';
        my $created  = time2iso($old_build->created_time);

        my $net_build = {
                          'languages_id' => $existing_lang->id,
                          'editions_id'  => $existing_edt->id,
                          'version'      => $version,
                          'path'         => $path,
                          'location'     => $location,
                          'created'      => $created
                        };
        my $exist_build = $net_bld->search($net_build)->first;
        $exist_build = $net_bld->create($net_build) if !defined $exist_build;
        
    }
    else {
        print "Problem: ".$old_build->build_path."\n";
    }
    print "|";
}
print "\n", "=" x 70, "\n";
=cut

# +==== Upgrade Whiteboard
# foreach my $old_report ( $old_whitebord->search(undef, {rows => 20, order_by => 'id DESC'}) ) {
foreach my $old_report ($old_whitebord->all ) {
    my $msg = $old_report->letterbody;
    my $parser = new QAInfo::DataSource::EmailReports($msg);
    my $data = $parser->parse;

    # Skip for letters without testplans
    unless ($data->{'test_plan_name'}) {
        print " Skip: ".$data->{'head_subj'}."\n";
        next;
    }

    # Find or create host (COMPUTER)
    my $comp_name = undef;
    if ( $data->{'computer_name'} ) {
        my $comp = $comp_rs->find_or_create({name => $data->{'computer_name'} });
        $comp_name = $comp->name;
    }
    else {
        warn "Computer name not found in data hash";
        dump $data;
        print " Skip: ".$data->{'head_subj'}."\n";next;
        
    }

    # Find or create OS
    my $os_id = undef;
    if ( $data->{'os_info'} ) {
        my $os = $os_rs->find_or_create({name => $data->{'os_info'}});
        $os->id($schema->storage->last_insert_id) if !$os->id;
        $os_id = $os->id;
    }
    else {
        warn "OS name not found in data hash";
        print " Skip: ".$data->{'head_subj'}."\n";next;
    }

    # Find or create User
    my $user_id = undef;
    if ( $data->{'sender_name'} ) {
        my $user = $users_rs->find_or_create({name => $data->{'sender_name'}});
        $user->id($schema->storage->last_insert_id) if !$user->id;
        $user_id = $user->id;
    }
    else {
        warn "User name not found in data hash";
        print " Skip: ".$data->{'head_subj'}."\n";next;
    }

    # Find or create Testplan
    my $test_plan_id = undef;
    if ( $data->{'test_plan_name'} ) {
        my $test_plan = $tp_rs->find_or_create({name => lc($data->{'test_plan_name'}) });
        $test_plan->id($schema->storage->last_insert_id) if !$test_plan->id;
        $test_plan_id = $test_plan->id;
    }
    else {
        warn "test_plan_name  not found in data hash";
        print " Skip: ".$data->{'head_subj'}."\n";next;
    }

    # Find or create edition
    my $edition_id = undef;
    if ( $data->{'edition_name'} ) {
        my $edition_record = {
                               'name'       => $data->{'edition_name'},
                               'protection' => $data->{'edition_protect'},
                               'media'      => $data->{'edition_media'},
                               'build_type' => $data->{'edition_type'}
                             };

        my $edition = $edt_rs->find_or_create($edition_record);
        $edition->id($schema->storage->last_insert_id) if !$edition->id;
        $edition_id = $edition->id;
    }
    else {
        warn "edition  not found in data hash";
        print " Skip: ".$data->{'head_subj'}."\n";next;
    }

    # Search for existing language
    my $language_id = undef;
    if ( $data->{'language'} ) {
        my $language = $lng_rs->search_like({name => $data->{'language'}})->first;
        $language_id = $language->id;
    }
    else {
        warn "language not found in data base";
        print " Skip: ".$data->{'head_subj'}."\n";next;
    }

    # Search or create new upgrade info record
    my $upgrade_info_id = undef;
    if ( $data->{'upgrade_id'} ) {
        my $upgrade_info = $upg_rs->find_or_create( {id => $data->{'upgrade_id'}} );
        $upgrade_info_id = $upgrade_info->id;
    }

    # Create results_id. 
    # First: 
    # TODO....

    my $rep = {
                 'os_id'          => $os_id,
                 'results_id'     => undef,
                 'users_id'       => $user_id,
                 'testplans_id'   => $test_plan_id,
                 'upgradeinfo_id' => $upgrade_info_id,
                 'editions_id'    => $edition_id,
                 'computers_name' => $comp_name,
                 'languages_id'   => $language_id,
                 'subject'        => $data->{'head_subj'},
                 'version'        => $data->{'version'},
                 'stat'           => $data->{'statistics'},
                 'comments'       => $data->{'comments'},
                 'links'          => $data->{'links'},
                 'mail_time'      => $data->{'head_date'},
                 'created'        => $data->{'head_date'},
                 'modified'       => $data->{'head_date'},
                 'verdict'        => $data->{'verdict'},
              };

    my $report = $rep_rs->find_or_create($rep);
    $report->id($schema->storage->last_insert_id) if !$report->id;
    
    # TODO: Add raw mail saving

    
}


